package ru.brostudios.cosmicdonutlivewallpapers;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.content.Context;
import android.opengl.GLSurfaceView;
import android.service.wallpaper.WallpaperService;
import android.util.Log;
import android.view.SurfaceHolder;

public class LiveWallpapersService extends WallpaperService {
	
    public LiveWallpapersService() {}
	
	@Override
	public void onCreate() {
		super.onCreate();
	}
	
	@Override
	public Engine onCreateEngine() {
		return new LiveWallpapersEngine();
	}

    @Override
    public void onDestroy() {
    	super.onDestroy();
    }
    
    public class LiveWallpapersEngine extends Engine {
    	
    	private LiveWallpapersGLSurfaceView glSurfaceView;

    	public LiveWallpapersEngine() {}
    	
        @Override
        public void onCreate(SurfaceHolder surfaceHolder) {
        	super.onCreate(surfaceHolder);
        }
        
        @Override
        public void onSurfaceCreated(SurfaceHolder holder) {
        	super.onSurfaceCreated(holder);
        	glSurfaceView = new LiveWallpapersGLSurfaceView(LiveWallpapersService.this);
        	glSurfaceView.setRenderer(glSurfaceView);
        }

        @Override
        public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        	super.onSurfaceChanged(holder, format, width, height);
        }
        
        @Override
        public void onVisibilityChanged(boolean visible) {
        	super.onVisibilityChanged(visible);
        	if(visible) glSurfaceView.onResume();
        	else glSurfaceView.onPause();
        }
        
        @Override
        public void onSurfaceDestroyed(SurfaceHolder holder) {
        	super.onSurfaceDestroyed(holder);
        }
        
        @Override
        public void onDestroy() {
        	super.onDestroy();
        }
        
        public class LiveWallpapersGLSurfaceView extends GLSurfaceView implements GLSurfaceView.Renderer {
        	
        	private boolean isFirstLanch;
        	private int fps, maxfps;
	    	private int frames;
	    	private long time, timesum, timesleep, timeframe;
        	private CosmicDonut spacedonut = null;
        	
        	public LiveWallpapersGLSurfaceView(Context context) {
        		super(context);
        		isFirstLanch = true;
        		fps = 0;
				frames = 0;
				time = 0;
				timesum = 0;
				timesleep = 0;
				timeframe = 0;
				maxfps = 30;
        	}
        	
        	@Override
        	public void onSurfaceCreated(GL10 gl, EGLConfig config) {}

        	@Override
        	public void onSurfaceChanged(GL10 gl, int width, int height) {
        		gl.glMatrixMode(GL10.GL_PROJECTION);
        		gl.glLoadIdentity();
        		gl.glOrthof(-width/2f, width/2f, -height/2f, height/2f, -1.0f, 1.0f);
        		gl.glMatrixMode(GL10.GL_MODELVIEW);
        		gl.glLoadIdentity();
        		gl.glViewport(0, 0, width, height);
        		if(isFirstLanch) {        			
        			spacedonut = new CosmicDonut(LiveWallpapersService.this, gl, width, height);
        			isFirstLanch = false;
        		}
        		else {
        			spacedonut.Resume(gl, width, height);
        		}
        		time = System.currentTimeMillis();
        	}
        	
        	@Override
        	public void onDrawFrame(GL10 gl) {
        		spacedonut.Draw(gl);
				long frametime = System.currentTimeMillis() - time;
				time = System.currentTimeMillis();
				timeframe = (timeframe + frametime)/2;
				frames++;
				timesum += frametime;
				if(timesum >= 1000) {
					timesum -= 1000;
					if(timesum < 0) timesum = 0;
					fps = frames;
					frames = 0;
					//Log.d("", "fps = " + fps);
				}
				try {
					long sleep = 0;
					if(frames < maxfps) sleep = (1000 - timesum)/(maxfps - frames);
					else sleep = 1000 - timesum;
					if(sleep > 0) {
						timesleep = (timesleep + sleep)/2;
						Thread.sleep(timesleep);
					}
				} catch(Exception e) {}
        	}
        	
        	@Override
        	public void onResume() {
        		super.onResume();
        		fps = 0;
				frames = 0;
				timesum = 0;
				time = 0;
        	}
        	
        	@Override
        	public void onPause() {
        		super.onPause();
        		fps = 0;
				frames = 0;
				timesum = 0;
				time = 0;
        		if(spacedonut != null) spacedonut.Pause();
        	}
        	
        	@Override
        	public SurfaceHolder getHolder() {
        		return getSurfaceHolder();
        	}
        	
        }
    	
    }
	
}